package com.yang.modules.common.deploy;

import com.google.common.collect.Maps;
import com.netflix.discovery.DiscoveryClient;
import com.yang.common.amqp.MessageSender;
import com.yang.common.amqp.rabbit.constant.FanoutConstants;
import com.yang.common.core.domain.Result;
import com.yang.common.core.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.Optional;

/**
 * 部署优雅发版相关接口
 *
 * @author Billyang
 * @date 2024/9/18 14:35
 */
@Slf4j
@RestController
public class DeployController {

    @Autowired
    private RefreshHandler refreshHandler;

    @Autowired
    private MessageSender messageSender;

    @Autowired(required = false)
    private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;

    /**
     * 服务下线
     *
     * @return
     */
    @GetMapping("/offline")
    public Result<?> offline() {
        try {
            DiscoveryClient client = SpringContextUtil.getBean(DiscoveryClient.class);
            client.shutdown();

            // 通知其他服务刷新服务列表，即时中断请求流量
            Map<String, Object> params = Maps.newHashMap();
            params.put("application", SpringContextUtil.getProperty("spring.application.name"));
            params.put("type", "offline");
            messageSender.sendFanoutMessage(params, FanoutConstants.DEPLOY.EXCHANGE);

            // 下线MQ监听器
            Optional.ofNullable(rabbitListenerEndpointRegistry).ifPresent(RabbitListenerEndpointRegistry::stop);
            return Result.success();
        } catch (Exception e) {
            log.error("offline error", e);
            return Result.fail(ExceptionUtils.getMessage(e));
        }
    }

    /**
     * 刷新注册列表
     *
     * @return
     */
    @GetMapping("/refresh")
    public Result<?> refresh() {
        refreshHandler.refresh();
        return Result.success();
    }
}
